#ifdef MSVC
	#include "SDL_image.h"
#else
	#include "SDL/SDL_image.h"
#endif

#include "renderer.h"
#include "logger.h"
#include "constants.h"
#include <sstream>

#include "spritesheet.h"

/*
 * Това е клас за spritesheet, взет от картинка. Всички sprite-ове са с еднакъв размер.
 * Поддържа (бърз - O(1)) оператор[], който връща съответния Sprite.
 * Също така, държи копие на оригиналния spritesheet.
 * Тоест, пази всички картинки *два пъти* в паметта.
 * Вбъдеще, това може да се промени.
 * */
Spritesheet::Spritesheet(const char * filename, const int _block_size, bool transparent)
{
    block_size = _block_size;
    std::stringstream name;
    name<<"Loading spritesheet: "<<filename;
    log_message(name);
    spritesheet = load_image(filename);
    std::stringstream s;
    s<<"Dimensions are: ("<<spritesheet->w<<", "<<spritesheet->h<<")";
    log_message(s);
    
    int num_sprites = (spritesheet->w/block_size) * (spritesheet->h/block_size);

    std::stringstream ns;
    ns<<"Trying to separate into "<<num_sprites<<" sprites";
    log_message(ns);
    int index;
    SDL_Rect clipRect;
    clipRect.w = block_size;
    clipRect.h = block_size;
    sprites = new SDL_Surface *[num_sprites];
    for(int x=0;x<(spritesheet->w/block_size);x++)
        for(int y=0;y<(spritesheet->h/block_size);y++)
        {
            index = y*(spritesheet->w/block_size) + x;
            clipRect.x = x*block_size;
            clipRect.y = y*block_size;

            sprites[index] = CreateSurface(block_size, block_size, spritesheet);
            if(transparent)
                sprites[index] = transparent_sprite(sprites[index]);

            apply_surface(0, 0, spritesheet, sprites[index], &clipRect);
        }
}

Spritesheet::~Spritesheet()
{
    int num_sprites = (spritesheet->w/block_size) * (spritesheet->h/block_size);
    SDL_FreeSurface(spritesheet);
    for(int x=0;x<num_sprites;x++)
        SDL_FreeSurface(sprites[x]);
    delete[] sprites;
}

/*
 * Ползата от тази реализация на операторите е, че призраците и Пакман 
 * не се налага да имат собствени масиви със спрайтове.
 * Т.е. изключително лесно може да се промени външния вид на някой герой.
 * */
SDL_Surface * Spritesheet::operator()(const int row, const int col)
{
    int index = row*(spritesheet->w/block_size) + col;
    return sprites[index];
}

SDL_Surface * Spritesheet::operator[](const int ind)
{
    return sprites[ind];
}
